﻿#include <Windows.h>
//#include <processthreadsapi.h>
#include <cstdio>
#include <ctime>

const int MAX_SEM_COUNT = 3;
HANDLE g_Semaphore;

typedef struct producer_s
{
	int nums;
	int iinterval;
} producer, * pproducer;

typedef struct consumer_s
{
	int num;
	int keyno;
	int iinterval;
	int name;
} consumer, * pconsumer;

void time_count(int interval = 2)
{
	time_t now = time(0);
	struct tm time_obj;
	localtime_s(&time_obj, &now);
	int t2 = 0;
	

	printf("current time[%02d:%02d:%02d]\n", time_obj.tm_hour, time_obj.tm_min, time_obj.tm_sec);
	if ((time_obj.tm_min + interval) >= 60)
	{
		t2 = (time_obj.tm_hour + 1) < 24 ? time_obj.tm_hour + 1 : 0;
		printf("\n[%02d:%02d:%02d] would be comming\n", t2, (time_obj.tm_min + interval) - 60, time_obj.tm_sec);
	}
	else
	{
		printf("\n[%02d:%02d:%02d] would be comming\n", time_obj.tm_hour, time_obj.tm_min + interval, time_obj.tm_sec);
	}
}

void mykey_press_release_u(int keyno = 1)
{
	if (1 == keyno)
	{
		keybd_event(0x11, 0, 0, 0);
		keybd_event(0x31, 0, 0, 0);
		keybd_event(0x31, 0, KEYEVENTF_KEYUP, 0);
		keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0);
	}
	else if (2 == keyno)
	{
		keybd_event(0x11, 0, 0, 0);
		keybd_event(0x32, 0, 0, 0);
		keybd_event(0x32, 0, KEYEVENTF_KEYUP, 0);
		keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0);
	}
	else if (3 == keyno)
	{
		keybd_event(0x11, 0, 0, 0);
		keybd_event(0x33, 0, 0, 0);
		keybd_event(0x33, 0, KEYEVENTF_KEYUP, 0);
		keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0);
	}
}

void getContentFromClipboared(HWND hData, HWND phw)
{   //#[get content from clipboard]#
	OpenClipboard(phw);
	EmptyClipboard();

	SetClipboardData(CF_UNICODETEXT, hData);
	GetClipboardData(CF_UNICODETEXT);
	CloseClipboard();
	SendMessage(phw, WM_PASTE, 0, 0);
	//Sleep(1000);
	// Ctrl + V
	//keybd_event(0x11, 0, 0, 0);
	//keybd_event(0x56, 0, 0, 0);
	//keybd_event(0x56, 0, KEYEVENTF_KEYUP, 0);
	//keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0);
}

void MyWndProc(int keyno = 1, int iinterval = 2)
{
	//LPPOINT pointOld;
	POINT point;
	LPWSTR pData; 
	//wchar_t pData;
	wchar_t content[6];
	HWND phw, hData;
	//const CString lis[2] = { "#加油", "#打卡" };
	//content = lis[0];
	lstrcpy(content, L"#打卡");
	if (2 == keyno)
	{
		lstrcpy(content, L"#美滋滋");
	}

	hData = (HWND)GlobalAlloc(GMEM_MOVEABLE, sizeof(content));
	pData = (LPWSTR)GlobalLock(hData);
	lstrcpy(pData, content);

	point.x = 1347;
	point.y = 761;
	/*pointOld->x = 1347;
	pointOld->y = 761;*/
	//GetCursorPos(pointOld);
	mykey_press_release_u(keyno);
	Sleep(4000);
	time_count(iinterval);
	Sleep(1000);

	phw = WindowFromPoint(point);
	ShowWindow(phw, SW_SHOW);
	SetCursorPos(1347, 761);
	mouse_event(MOUSEEVENTF_LEFTDOWN, 1394, 764, 0, 0);
	mouse_event(MOUSEEVENTF_LEFTUP, 1394, 764, 0, 0);
	Sleep(2000);

	getContentFromClipboared(hData, phw);
	Sleep(1000);
	//SendMessage(phw, WM_PASTE, 0, 0);
	// Enter Key Press
	keybd_event(VK_RETURN, 0, 0, 0);
	keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
	Sleep(1000);
	//MessageBox(NULL, "MyWndProc", NULL, MB_OK);
	//printf("MyWndProc\n");

}

DWORD WINAPI producerfun(LPVOID lpParam)
{
	producer_s *prod;
	prod = (producer_s*)lpParam;
	long count;

	for (size_t i = 0; i < 2; ++i)
	{
		WaitForSingleObject(g_Semaphore, 0L);
		printf("pro-current thread name is: %d\n", GetCurrentThreadId());
		ReleaseSemaphore(g_Semaphore, 1, &count);
		Sleep(1000 * 14);
	}

	for (size_t i = 0; i < prod->nums; ++i)
	{
		Sleep(2000);
		WaitForSingleObject(g_Semaphore, 0L);
		printf("pro-current thread name is: %d\n", GetCurrentThreadId());
		ReleaseSemaphore(g_Semaphore, 1, &count);
		Sleep(1000 * 60 * prod->iinterval);
	}

	return 0;
}

DWORD WINAPI consumerfun(LPVOID lpParam)
{
	consumer_s *consum;
	consum = (consumer_s*)lpParam;
	long count;
	for (size_t i = 0; i < consum->num; ++i)
	{
		Sleep(2000);
		WaitForSingleObject(g_Semaphore, 12000);
		printf("----wait for producer running----\n");
		printf("cer-current thread name is: %d\n", GetCurrentThreadId());
		MyWndProc(consum->keyno, consum->iinterval);
		ReleaseSemaphore(g_Semaphore, 1, &count);
		Sleep(1000 * 60 * consum->iinterval);
	}
	return 0;
}

int main(void)
{
	HANDLE Tri[3];
	DWORD ThreadID[3];
	printf("----start----\n");
	g_Semaphore = CreateSemaphore(NULL, 0, MAX_SEM_COUNT, NULL);

	if (g_Semaphore == NULL)
	{
		printf("Create Semaphore failed!: %d\n", GetLastError());
	}

	pproducer pprod = (pproducer)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
		sizeof(producer_s));

	if (pprod == NULL)
	{
		printf("Create producer failed!: %d\n", GetLastError());
	}

	pprod->nums = 40;
	pprod->iinterval = 12;

	pconsumer pconsum1 = (pconsumer)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
		sizeof(consumer_s));
	
	pconsumer pconsum2 = (pconsumer)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
		sizeof(consumer_s));

	if (pconsum1 == NULL)
	{
		printf("Create consumer1 failed!: %d\n", GetLastError());
	}

	pconsum1->num = 40;
	pconsum1->keyno = 1;
	pconsum1->iinterval = 20;
	pconsum1->name = 1;

	if (pconsum2 == NULL)
	{
		printf("Create consumer2 failed!: %d\n", GetLastError());
	}

	pconsum2->num = 40;
	pconsum2->keyno = 2;
	pconsum2->iinterval = 35;
	pconsum2->name = 2;

	Tri[1] = CreateThread(NULL, 0, consumerfun, pconsum1, 0, &ThreadID[1]);
	Tri[2] = CreateThread(NULL, 0, consumerfun, pconsum2, 0, &ThreadID[2]);
	Tri[0] = CreateThread(NULL, 0, producerfun, pprod, 0, &ThreadID[0]);

	WaitForSingleObject(Tri[1], INFINITE);
	WaitForSingleObject(Tri[2], INFINITE);
	WaitForSingleObject(Tri[0], INFINITE);

	CloseHandle(Tri[0]);
	CloseHandle(Tri[1]);
	CloseHandle(Tri[2]);

	HeapFree(GetProcessHeap(), 0, pprod);
	HeapFree(GetProcessHeap(), 0, pconsum1);
	HeapFree(GetProcessHeap(), 0, pconsum2);

	pprod = NULL;
	pconsum1 = NULL;
	pconsum2 = NULL;
	delete[] ThreadID;

	printf("Hello Window2\n");
	return 0;
}
